1 /**
2  * @author Stéphane Roucheray
3  * @extends jQuery
4  */

5
6 jQuery.fn.dynamicForm = function (plusElmnt, minusElmnt, options){
7     
var source = jQuery(this),
8     minus = jQuery(minusElmnt),
9     plus = jQuery(plusElmnt),
10     template = source.clone(
true),
11     fieldId =
0,
12     formFields =
"input, checkbox, select, textarea",
13     insertBefore = source.next(),
14     clones = [],
15     defaults = {
16         duration:
1000
17     };
18     
19     
// Extend default options with those provided
20     options = $.extend(defaults, options);
21     
22     isPlusDescendentOfTemplate = source.find(
"*").filter(function(){
23         
return this == plus.get(0);
24     });
25     
26     isPlusDescendentOfTemplate = isPlusDescendentOfTemplate.length >
0 ? true : false;
27     
28     function normalizeElmnt(elmnt){
29         elmnt.find(formFields).each(function(){
30             
var nameAttr = jQuery(this).attr("name"),
31             idAttr = jQuery(
this).attr("id");
32
33             
/* Normalize field name attributes */
34             
if (!nameAttr) {
35                 jQuery(
this).attr("name", "field" + fieldId + "[]");
36             }
37             
38             
if (!/\[\]$/.exec(nameAttr)) {
39                 jQuery(
this).attr("name", nameAttr + "[]");
40             }
41             
42             
/* Normalize field id attributes */
43             
if (idAttr) {
44                 
/* Normalize attached label */
45                 jQuery(
"label[for='"+idAttr+"']").each(function(){
46                     jQuery(
this).attr("for", idAttr + fieldId);
47                 });
48                 
49                 jQuery(
this).attr("id", idAttr + fieldId);
50             }
51             fieldId++;
52         });
53     };
54     
55     
/* Hide minus element */
56     minus.hide();
57     
58     
/* If plus element is within the template */
59     
if (isPlusDescendentOfTemplate) {
60         function clickOnPlus(
event){
61             
var clone,
62             currentClone = clones[clones.length -
1] || source;
63             
event.preventDefault();
64             
65             
/* On first add, normalize source */
66             
if (clones.length == 0) {
67                 normalizeElmnt(source);
68                 currentClone.find(minusElmnt).hide();
69                 currentClone.find(plusElmnt).hide();
70             }
else{
71                 currentClone.find(plusElmnt).hide();
72             }
73             
74             
/* Clone template and normalize it */
75             clone = template.clone(
true).insertAfter(clones[clones.length - 1] || source);
76             normalizeElmnt(clone);
77             
78             
/* Normalize template id attribute */
79             
if (clone.attr("id")) {
80                 clone.attr(
"id", clone.attr("id") + clones.length);
81             }
82             
83             
84             plus = clone.find(plusElmnt);
85             minus = clone.find(minusElmnt);
86             
87             minus.
get(0).removableClone = clone;
88             minus.click(clickOnMinus);
89             plus.click(clickOnPlus);
90             
91             
if (options.limit && (options.limit - 2) > clones.length) {
92                 plus.show();
93             }
else{
94                 plus.hide();
95             }
96             
97             clones.push(clone);
98         }
99         
100         function clickOnMinus(
event){
101             
event.preventDefault();
102             
103             
if (this.removableClone.effect && options.removeColor) {
104                 that =
this;
105                 
this.removableClone.effect("highlight", {
106                     color: options.removeColor
107                 }, options.duration, function(){that.removableClone.
remove();});
108             }
else {
109             
110                 
this.removableClone.remove();
111             }
112             clones.splice(clones.indexOf(
this.removableClone),1);
113             
if (clones.length == 0){
114                 source.find(plusElmnt).show();
115             }
else{
116                 clones[clones.length -
1].find(plusElmnt).show();
117             }
118         }
119         
120         
/* Handle click on plus */
121         plus.click(clickOnPlus);
122         
123         
/* Handle click on minus */
124         minus.click(function(
event){
125             
126         });
127         
128     }
else{
129     
/* If plus element is out of the template */
130         
/* Handle click on plus */
131         plus.click(function(
event){
132             
var clone;
133             
134             
event.preventDefault();
135             
136             
/* On first add, normalize source */
137             
if (clones.length == 0) {
138                 normalizeElmnt(source);
139                 jQuery(minusElmnt).show();
140             }
141             
142             
/* Clone template and normalize it */
143             clone = template.clone(
true).insertAfter(clones[clones.length - 1] || source);
144             
if (clone.effect && options.createColor) {
145                 clone.effect(
"highlight", {color:options.createColor}, options.duration);
146             }
147             normalizeElmnt(clone);
148             
149             
/* Normalize template id attribute */
150             
if (clone.attr("id")) {
151                 clone.attr(
"id", clone.attr("id") + clones.length);
152             }
153             
if (options.limit && (options.limit - 3) < clones.length) {
154                 plus.hide();
155             }
156             clones.push(clone);
157         });
158         
159         
/* Handle click on minus */
160         minus.click(function(
event){
161             
event.preventDefault();
162             
var clone = clones.pop();
163             
if (clones.length >= 0) {
164                 
if (clone.effect && options.removeColor) {
165                     that =
this;
166                     clone.effect(
"highlight", {
167                         color: options.removeColor, mode:
"hide"
168                     }, options.duration, function(){clone.
remove();});
169                 }
else {
170                     clone.
remove();
171                 }
172             }
173             
if (clones.length == 0) {
174                 jQuery(minusElmnt).hide();
175             }
176             plus.show();
177         });
178     }
179     
180 };


Gõ tìm kiếm nhanh...